package com.hongru.ebean;

import com.alibaba.fastjson.JSONObject;
import com.hongru.util.JwtUtil;
import com.hongru.util.ReflectUtils;
import com.hongru.util.StringUtil;
import com.hongru.vo.LoginUser;
import com.hongru.vo.SysUserCacheInfo;
import io.ebean.DB;
import io.ebean.ExpressionList;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.util.*;
import java.util.stream.Collectors;


/**
 * @Description
 * @Copyright (c) 1998-2022 北京新鸿儒世纪网络技术有限公司 All Rights Reserved.
 * @Url https://www.xinhongru.com
 * @ClassName EbeanUtil
 * @Author salter <salter@vip.163.com>
 * @Version V1.0.0
 * @Since 1.0
 * @Date 2022/1/7 11:53
 */
@Slf4j
@Component
public class EbeanUtil {

    private static String packageName;

    @Value("${generate.packageName}")
    public void setPackageName(String packageName) {
        EbeanUtil.packageName = packageName;
    }

    public static void changeColumnNum(String className, String columnName, String id, String num) {
        String prefix = StringUtil.humpToUnderline(className).split("_")[0];
        String classForName = packageName + "." + prefix + "." + "entity." + className;
        try {
            Class<?> aClass = Class.forName(classForName);
            ExpressionList<?> el = EbeanUtil.initExpressionList(aClass).where().idEq(id);
            el.asUpdate().setRaw(columnName + "=" + columnName + num).update();
        } catch (ClassNotFoundException ignored) {

        }
    }

    public static <T> HongRuPage<T> pageList(JSONObject searchObj, Class<T> tClass) {
        ExpressionList<T> el = initExpressionList(searchObj, tClass);
        HongRuPage<T> page = new HongRuPage<>(searchObj.getInteger("pageNo"), searchObj.getInteger("pageSize"), searchObj.getString("column"), searchObj.getString("order"));
        String[] orderColumns = page.getColumn().split(",");
        String[] order = page.getOrder().split(",");
        StringBuilder orderSb = new StringBuilder();
        for (int i = 0; i < orderColumns.length; i++) {
            if (ReflectUtils.checkFieldExist(orderColumns[i], tClass)) {
                String orderStr = "";
                if (order.length > i) {
                    orderStr = order[i];
                }
                orderSb.append(orderColumns[i]).append(" ").append(orderStr);
                if (i == orderColumns.length - 1) {
                    continue;
                }
                orderSb.append(",");
            }
        }
        el.orderBy(orderSb.toString());
        el.setFirstRow((page.getPageNo() - 1) * page.getPageSize());
        el.setMaxRows(page.getPageSize());
        page.setRecords(el.findList());
        page.setTotal(el.findCount());
        return page;
    }

    public static <T> void status(StatusDto statusDto, Class<T> tClass) {
        DB.update(tClass).set("status", statusDto.getChecked()).where().idEq(statusDto.getId()).update();
    }

    public static <T> void field(String field, StatusDto statusDto, Class<T> tClass) {
        DB.update(tClass).set(field, statusDto.getChecked()).where().idEq(statusDto.getId()).update();
    }

    public static <T> void sortNo(SortNoDto sortNoDto, Class<T> tClass) {
        DB.update(tClass).set("sortNo", sortNoDto.getSortNo()).where().idEq(sortNoDto.getId()).update();
    }

    public static <T> void delete(String id, Class<T> tClass) {
        DB.update(tClass).set("deleted", true).where().idEq(id).update();
    }

    public static <T> void deleteBatch(String ids, Class<T> tClass) {
        String[] idArr = ids.split(",");
        DB.update(tClass).set("deleted", true).where().idIn(idArr).update();
    }

    public static <T> T findCodeByLevel(Integer level, Class<T> tClass) {
        T t = DB.find(tClass).where().eq("level", level).orderBy("createTime desc").setMaxRows(1).findOne();
        return t;
    }

    public static <T> ExpressionList<T> initExpressionList(Class<T> tClass) {
        return initExpressionList(new JSONObject(), tClass);
    }

    public static <T> ExpressionList<T> initExpressionList(JSONObject searchObj, Class<T> tClass) {
        ExpressionList<T> el = DB.find(tClass).where();
        el.eq("deleted", false);
        SysUserCacheInfo sysUserCacheInfo = JwtUtil.getSysUserCacheInfo();
        Map<String, String> fieldMap = new HashMap<>();
        for (Field field : ReflectUtils.getAllFields(tClass)) {
            fieldMap.put(field.getName(), field.getType().getName());
        }
        for (String key : searchObj.keySet()) {
            String formatKey = key;
            String fieldType = fieldMap.get(formatKey);
            if (null != fieldMap.get("lbsId") && null != sysUserCacheInfo && StringUtil.isNotEmpty(sysUserCacheInfo.getLbsId())) {
                el.eqOrNull("lbsId", sysUserCacheInfo.getLbsId());
            }
            if (key.contains("_notNull")) {
                if (StringUtil.isNotEmpty(searchObj.getString(key))) {
                    el.like(key.split("_")[0], "%" + searchObj.getString(key).trim() + "%");
                } else {
                    el.isNotNull(key.split("_")[0]);
                }
                continue;
            }
            if (null == searchObj.get(key) || "" == searchObj.get(key)) {
                continue;
            }
            if (key.equals("pageSize") || key.equals("pageNo") || key.equals("column") || key.equals("order")) {
                continue;
            }
            //自定义查询
            if (key.contains("_eq")) {
                el.eq(key.split("_")[0], searchObj.getString(key));
                continue;
            }
            //区间查询
            if (key.contains("_begin")) {
                el.gt(key.split("_")[0], searchObj.getString(key));
                continue;
            }
            if (key.contains("_end")) {
                el.lt(key.split("_")[0], searchObj.getString(key));
                continue;
            }
            //分类in查询
            if (key.contains("categoryCode") && searchObj.getString(key).contains(",")) {
                String[] valueArr = searchObj.getString(key).split(",");
                el.in(formatKey, valueArr);
                continue;
            }
            //级联查询
            if (key.contains("_")) {
                formatKey = key.replace("_", ".");
                el.like(formatKey, "%" + searchObj.getString(key).trim() + "%");
                continue;
            }
            if ("0".equals(searchObj.getString(key))) {
                el.eq(formatKey, searchObj.getString(key).trim());
            }

            if (StringUtil.isEmpty(fieldType)) {
                continue;
            }
            if (fieldType.equals("java.lang.Boolean")) {
                el.eq(formatKey, searchObj.getString(key).trim());
            } else if (fieldType.equals("java.lang.Integer")) {
                el.eq(formatKey, searchObj.getString(key).trim());
            } else if (key.contains("Id")) {
                el.eq(formatKey, searchObj.getString(key).trim());
            } else {
                el.like(formatKey, "%" + searchObj.getString(key).trim() + "%");
            }
        }
        return el;
    }


}
